package sgs.common.utils;

import org.apache.commons.lang3.StringUtils;
import sgs.skin.SkinFileProcessor;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.logging.Level;

public class DataCache {
    /**
     * 特殊皮肤代码到角色代码的映射，不同的版本，加上ver.作为区分：ver. + skin code -> character code
     */
    public static Map<String, String> skinCodeToChrctCodeMap = new HashMap<>();
    /**
     * 角色代码到特殊皮肤代码的映射，不同的版本，加上ver.作为区分：ver. + character code -> skin code
     */
    public static Map<String, String> characterCodeToSkinCodeMap = new HashMap<>();
    /**
     * 角色代码到皮肤名称的映射，不同的版本，加上ver.作为区分：ver. + character code -> skin name, 例：ZN.001 -> 蜀.刘备 , OL.1->蜀.刘备
     */
    public static Map<String, String> characterCodeToNameMap = new HashMap<>();
    /**
     * 皮肤名称到皮肤目录的映射，skin name -> skin dir，例：蜀.刘备 -> 蜀/001.刘备 , 蜀.黄月英 -> 蜀/007.黄月英.女
     */
    public static Map<String, String> skinNameToDirMap = new HashMap<>();
    /**
     * 已存在的皮肤代码：ver. + skin code
     */
    public static Set<String> existSkinCodes = new HashSet<>(); // 使用HashSet以加速查找
    /**
     * 已存在的高清皮肤代码：ver. + skin code
     */
    public static Set<String> existMaxSkinCodes = new HashSet<>(); // 使用HashSet以加速查找
    private static String FILE_CODE_ZN = Config.INSTANCE.getProperty("file.code.zn");
    private static String FILE_CODE_OL = Config.INSTANCE.getProperty("file.code.ol");
    private static String FILE_CODE_MB = Config.INSTANCE.getProperty("file.code.mb");
    private static String DIR_SKIN = Config.INSTANCE.getProperty("dir.skin");

    public static void init() throws Exception {
        initCacheMapByCodeFile(FILE_CODE_ZN, VersionEnum.ZN);
        initCacheMapByCodeFile(FILE_CODE_OL, VersionEnum.OL);
        initCacheMapByCodeFile(FILE_CODE_MB, VersionEnum.MB);

        initExistSkinCodes(DIR_SKIN);
    }


    /**
     * 初始化编码文件映射 <br/>
     * 例如：001 -> 蜀.刘备 , 007->蜀.黄月英.女
     *
     * @param codeFilepath 编码文件路径
     * @param ver          版本
     * @author yaenli
     * @since 2024-6-4
     */
    private static void initCacheMapByCodeFile(String codeFilepath, VersionEnum ver) throws Exception {
        if (StringUtils.isBlank(codeFilepath)) {
            Logger.log(Level.WARNING, ver + "编码文件路径为空，跳过初始化");
            return;
        }

        ArrayList<String[]> codeList = FileUtils.readCsv(codeFilepath, "UTF-8");
        for (String[] col : codeList) { // country,name,sex,characterCode,skinCode
            if ("势力".equals(col[0]) || StringUtils.isAnyBlank(col[1], col[3])) {
                continue;
            }
            // 生成目录: country/ver.characterCode.name.sex，其中.sex仅女性添加，10周年版本不添加ver.
            String name = String.join(".", col[0], col[1]);
            String folder = "女".equals(col[2]) ? String.join(".", col[3], col[1], col[2]) : String.join(".", col[3], col[1]);
            String dir = VersionEnum.ZN.equals(ver) ? col[0] + "/" + folder : col[0] + "/" + ver + "." + folder;

            // 不同的版本，加上ver.作为区分。 例：ZN.001 -> 蜀.刘备 , OL.1->蜀.刘备
            characterCodeToNameMap.putIfAbsent(ver + "." + col[3], name);
            // 映射目录，例：蜀.刘备 -> 蜀/001.刘备 , 蜀.黄月英 -> 蜀/007.黄月英.女
            skinNameToDirMap.putIfAbsent(name, dir);

            if (StringUtils.isNotBlank(col[4])) {
                // 皮肤代码 -> 角色代码
                skinCodeToChrctCodeMap.put(ver + "." + col[4], col[3]);
                // 角色代码 -> 皮肤代码
                characterCodeToSkinCodeMap.put(ver + "." + col[3], col[4]);
            }
        }
    }

    private static void initExistSkinCodes(String skinDirPath) {
        Path directory = Paths.get(skinDirPath);

        try {
            Files.walk(directory)
                    .filter(Files::isRegularFile) // 确保只处理文件
                    .filter(FileUtils::isImageByExtension)// 仅处理图片文件
                    .forEach(path -> {
                        String fileName = path.getFileName().toString(); // 获取文件名
                        String skinCode = SkinFileProcessor.getSkinCodeBySkinFile(fileName); // 按规则提取皮肤代码
                        if (skinCode != null) { // 确保提取成功
                            VersionEnum ver = VersionEnum.getByFileName(fileName);
                            if (fileName.contains(".max")) {
                                existMaxSkinCodes.add(ver + "." + skinCode);
                            }else {
                                existSkinCodes.add(ver + "." + skinCode);
                            }
                        }
                    });
        } catch (IOException e) {
            Logger.log(Level.SEVERE, "Error walking through the file tree: " + e.getMessage(), e);
            throw new RuntimeException(e);
        }
    }
}
